package pl.un4giv3n.mightvsmagic.action;

import java.util.ArrayList;
import java.util.List;

import javax.mail.NoSuchProviderException;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import pl.un4giv3n.mightvsmagic.entity.ActivityType;
import pl.un4giv3n.mightvsmagic.entity.User;
import pl.un4giv3n.mightvsmagic.entity.UserActivity;
import pl.un4giv3n.mightvsmagic.utils.ActivityLogUtil;
import pl.un4giv3n.mightvsmagic.utils.MailSender;
import pl.un4giv3n.mightvsmagic.utils.UserUtil;

import com.obixlabs.commons.ObixException;
import com.obixlabs.commons.security.MinLowerCaseCharsPasswordRequirement;
import com.obixlabs.commons.security.MinNonAlpaNumericCharsPasswordRequirement;
import com.obixlabs.commons.security.MinNumericCharsPasswordRequirement;
import com.obixlabs.commons.security.MinUpperCaseCharsPasswordRequirement;
import com.obixlabs.commons.security.PasswordGenerator;
import com.obixlabs.commons.security.PasswordGeneratorDefaultImpl;
import com.obixlabs.commons.security.PasswordRequirement;
import com.obixlabs.commons.security.SimpleAlphaCharsFillPasswordRequirement;

/**
 * @author andrzejewskia
 * regenerates password, and sends it with email
 *
 */
public class RegeneratePasswordAction extends PersistenceAction{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = Logger.getLogger(RegeneratePasswordAction.class.getName());
	private String username;
	private String email;
	
	@Override
	public String execute() {
		EntityManager entityManager = getEntityManager();
		Query query = entityManager.createNamedQuery("find.user.by.login");
		query.setParameter("login", username);
		@SuppressWarnings("unchecked")
		List resultList = query.getResultList();
		if(resultList.isEmpty()){
			addActionError("Nie znaleziono użytkownika o podanej nazwie");
			entityManager.close();
			return INPUT;
		}
		User user = (User) resultList.get(0);
		if(!user.getEmail().equals(email)){
			addActionError("Nieprawidłowy adres email");
			entityManager.close();
			return INPUT;
		}
		try {
			String password = generatePassword();
			EntityTransaction transaction = entityManager.getTransaction();
			MailSender.send(user.getEmail(), MailSender.NEW_PASSWD_SUBJECT, MailSender.getNewPasswordMessage(username, password));
			transaction.begin();
			user.setPassword(UserUtil.encyptPassword(password));
			entityManager.merge(user);
			UserActivity activity = ActivityLogUtil.createActivity(ActivityType.CHANGE_PASSWORD, user.getId(),"Zmiana hasła");
			entityManager.persist(activity);
			entityManager.flush();
			transaction.commit();
			entityManager.close();
		} catch (NoSuchProviderException e) {
			LOG.error(e.getMessage(),e);
			addActionError("Błąd wysyłania wiadomości e-mail!");
			return INPUT;
		} catch (ObixException e) {
			LOG.error(e.getMessage(),e);
			addActionError("Błąd generowania hasła!");
			return INPUT;
		}
		addActionError("Wygenerowano nowe hasło. Sprawdź swoją pocztę.");
		return SUCCESS;
	}

	private String generatePassword() throws ObixException {
		int minimumPasswordLength = 8;

		//create an array containing the simplest password requirement
		List<PasswordRequirement> requirements =
			 new ArrayList<PasswordRequirement>();

		//add a simple fill requirement to give us an initial weak password
		requirements.add(new SimpleAlphaCharsFillPasswordRequirement(minimumPasswordLength));

		//add some strenghtening rules
		//at least one lowercase character
		requirements.add(new MinLowerCaseCharsPasswordRequirement());

		//at least one uppercase character
		requirements.add(new MinUpperCaseCharsPasswordRequirement());

		//at least one number
		requirements.add(new MinNumericCharsPasswordRequirement());

		//at least one punctuation character
		requirements.add(new MinNonAlpaNumericCharsPasswordRequirement());
		//create the generator
		PasswordGenerator generator = new PasswordGeneratorDefaultImpl();

		//then generate the password
		return generator.generatePassword(requirements);
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	
	

}
